<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello, world!</title>
    <style>
        * {
            font-family: 'Times New Roman', Times, serif;
            font-size: small;
            margin: 2px;
            padding: 2px;
        }

        h2 {
            background: linear-gradient(to top right, #777777, #eeeeee);
            border-radius: 3px;
            user-select: none;
        }

        label { user-select: none; }

        pre { font-family: "新宋体", 'Times New Roman'; }

        .container {
            border: 1px solid #cccccc;
            border-radius: 5px;
            box-shadow: 4px 4px 4px #bbbbbb;
            background-color: #eeeeee;
            position: absolute;
        }

        .result { width: 60px; }

        .xbtn {
            font-family: 黑体, Arial, Helvetica, sans-serif;
            border: solid 0px #ff0000;
            margin: 0;
            float: right;
        }

        .main { display: block; }
    </style>
</head>

<body>
    <div id="root">
        <div class="container">
            <h2>
                功率计算
                <span class="xbtn">x</span>
            </h2>
            <div class="main">
                <label for="">&nbsp;dbm转w</label>
                <input type="text" placeholder="单位dbm">
                <input class="result" type="text" readonly> <br>
                <label for="">&nbsp;w转dbm</label>
                <input type="text" placeholder="单位w">
                <input class="result" type="text" readonly> <br>
            </div>
        </div>
        <div class="container">
            <h2>
                进制转换
                <span class="xbtn">x</span>
            </h2>
            <div class="main">
                <label for="">10进制</label>
                <input type="text"> <br>
                <label for="">16进制</label>
                <input type="text"> <br>
                <label for="">&nbsp;&nbsp;2进制</label>
                <input type="text"> <br>
            </div>
        </div>
        <div class="container">
            <h2>
                文件读取
                <span class="xbtn">x</span>
            </h2>
            <div class="main">
                <input type="file" name="file" id="uploadText" multiple /> <br />
                <input type="file" name="file" id="uploadImage" multiple /> <br />
                <input type="file" name="file" id="uploadBin" multiple /> <br />

                <pre id="context" style="color:#0000ff;"></pre>
                <img id="image" />
                <pre id="contextBin" style="color:#0000ff;"></pre>
            </div>
        </div>
    </div>

    <script>
        var zxxDrag = function (eleBar, options) {
            if (!eleBar) {
                return;
            }
            // 默认数据
            var defaults = {
                target: eleBar,
                bounding: window,
                edgeLock: true,
                onMove: function () {},
                onEnd: function () {}
            };

            options = options || {};

            var params = {};
            for (var key in defaults) {
                if (typeof options[key] != 'undefined') {
                    params[key] = options[key];
                } else {
                    params[key] = defaults[key];
                }
            }

            // 拖拽元素
            var eleTarget = params.target;
            // 限制范围
            var bounding = params.bounding;
            var objBounding = bounding;

            // 事件类型处理
            var objEventType = {
                start: 'mousedown',
                move: 'mousemove',
                end: 'mouseup'
            };

            if ('ontouchstart' in document) {
                objEventType = {
                    start: 'touchstart',
                    move: 'touchmove',
                    end: 'touchend'
                };
            }

            // 坐标存储数据
            var store = {};
            eleBar.addEventListener(objEventType.start, function (event) {
                // IE 拖拽可能拖不动的处理
                if (!window.WeakMap || typeof document.msHidden != 'undefined') {
                    event.preventDefault();
                }
                // 兼顾移动端
                if (event.touches && event.touches.length) {
                    event = event.touches[0];
                }
                store.y = event.pageY;
                store.x = event.pageX;
                store.isMoving = true;
                store.top = parseFloat(getComputedStyle(eleTarget).top) || 0;
                store.left = parseFloat(getComputedStyle(eleTarget).left) || 0;

                if (params.edgeLock === true && bounding) {
                    if (bounding === window) {
                        objBounding = {
                            left: 0,
                            top: 0,
                            bottom: innerHeight,
                            right: Math.min(innerWidth, document.documentElement.clientWidth)
                        };
                    } else if (bounding.tagName) {
                        objBounding = bounding.getBoundingClientRect();
                    }

                    // 拖拽元素的 bounding 位置
                    var objBoundingTarget = eleTarget.getBoundingClientRect();

                    // 可移动范围
                    store.range = {
                        y: [objBounding.top - objBoundingTarget.top, objBounding.bottom - objBoundingTarget.bottom],
                        x: [objBounding.left - objBoundingTarget.left, objBounding.right - objBoundingTarget.right]
                    };
                }
            });
            document.addEventListener(objEventType.move, function (event) {
                if (store.isMoving) {
                    event.preventDefault();
                    // 兼顾移动端
                    if (event.touches && event.touches.length) {
                        event = event.touches[0];
                    }            

                    var distanceY = event.pageY - store.y;
                    var distanceX = event.pageX - store.x;
                    
                    // 边界的判断与chuli
                    if (params.edgeLock === true && bounding) {
                        var minX= Math.min.apply(null, store.range.x);
                        var maxX = Math.max.apply(null, store.range.x);
                        var minY= Math.min.apply(null, store.range.y);
                        var maxY = Math.max.apply(null, store.range.y);

                        if (distanceX < minX) {
                            distanceX = minX;
                        } else if (distanceX > maxX) {
                            distanceX = maxX;
                        }

                        if (distanceY < minY) {
                            distanceY = minY;
                        } else if (distanceY > maxY) {
                            distanceY = maxY;
                        }
                    }
                    
                    var top = store.top + distanceY;
                    var left = store.left + distanceX;

                    eleTarget.style.top = top + 'px';
                    eleTarget.style.left = left + 'px';

                    // 回调
                    params.onMove(left, top);
                }
            }, {
                passive: false
            });
            document.addEventListener(objEventType.end, function () {
                if (store.isMoving) {
                    store.isMoving = false;
                    params.onEnd();
                }            
            });
        };
    </script>
    <script>
        let $containers = document.querySelectorAll(".container");
        $containers.forEach((e, i) => {
            let $h2 = e.querySelector("h2");
            zxxDrag($h2, { target: e });

            let offset = $h2.clientHeight + 5;
            e.style.left = `${i * offset}px`;
            e.style.top = `${i * offset}px`;

            e.addEventListener('click', event => {
                $containers.forEach((each, index) => {
                    let zIndex = (index == i) ? 1 : 0;
                    each.style.zIndex = `${zIndex}`;
                });
            });

            // 隐藏窗口
            let $main = e.querySelector(".main");
            let $xbtn = $h2.querySelector(".xbtn");
            $xbtn.addEventListener("click", event => {
                if ($main.style.display === "none") {
                    $main.style.display = "block";
                    $xbtn.innerText = "x";
                } else {
                    $main.style.display = "none";
                    $xbtn.innerText = "o";
                }
            });

            // 双击窗口标题栏隐藏窗口
            $h2.addEventListener('dblclick', event => {
                if ($main.style.display === "none") {
                    $main.style.display = "block";
                    $xbtn.innerText = "x";
                } else {
                    $main.style.display = "none";
                    $xbtn.innerText = "o";
                }
            });
        });
    </script>

    <script>
        let uploadText = document.querySelector('#uploadText');
        let context = document.querySelector('#context');
        uploadText.addEventListener("change", function () {
            if (this.files.length === 0) {
                context.innerText = "";
                return;
            }

            let file = this.files[0];
            let reader = new FileReader();
            reader.readAsText(file);
            reader.onload = () => {
                console.log(reader.result);
                context.innerText = reader.result;
            };
        });

        let uploadImage = document.querySelector('#uploadImage');
        let image = document.querySelector('#image');
        uploadImage.addEventListener("change", function () {
            if (this.files.length === 0) {
                image.src = "";
                image.width = 0;
                image.height = 0;
                return;
            }
            let file = this.files[0];
            let reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = () => {
                image.src = reader.result;
                image.width = 600;
                image.height = 400;
            };
        });

        let uploadBin = document.querySelector('#uploadBin');
        let contextBin = document.querySelector('#contextBin');
        uploadBin.addEventListener("change", function () {
            if (this.files.length === 0) {
                contextBin.innerText = "";
                return;
            }

            let file = this.files[0];
            let reader = new FileReader();
            reader.readAsArrayBuffer(file);
            reader.onload = () => {
                let buf = new Uint8Array(reader.result);
                let length = buf.byteLength;
                let result = buf.slice(0, 100).map(e => e.toString(16)).join(' ');
                console.log(result);
                let mult_str = result.replace(/(.{48})/g, "$1\n");
                contextBin.innerText = `length: \n${length}\ncontent: \n${mult_str}`;
            };
        });
    </script>

</body>

</html>